package com.hmall.item.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.dto.PageDTO;
import com.hmall.common.dto.RequestParams;
import com.hmall.common.pojo.Item;
import com.hmall.item.mapper.ItemMapper;
import com.hmall.item.service.IItemService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Xinyi
 */
@Service
public class ItemService extends ServiceImpl<ItemMapper, Item> implements IItemService {

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RestHighLevelClient client;


    @Override
    public PageDTO<Item> selectSimpleSearch(RequestParams requestParams) {
      /*  RequestParams requestParams1 = new RequestParams();
        requestParams1.setKey("");
        requestParams1.setPage(1);
        requestParams1.setSize(20);
        requestParams1.setSortBy("default");


        LambdaQueryWrapper<Item> lqw = new LambdaQueryWrapper<>();
        IPage<Item> iPage = new Page<>(requestParams.getPage(), requestParams.getSize());
        PageDTO<Item> pageDTO = new PageDTO<>();


        ////////这里是第二注释
//        lqw.like(requestParams.getKey() != null && requestParams.getKey() != "", Item::getName, requestParams.getKey())
//                .eq(requestParams.getCategory() != null && requestParams.getCategory() != "", Item::getCategory, requestParams.getCategory())
//                .eq(requestParams.getBrand() != null && requestParams.getBrand() != "", Item::getBrand, requestParams.getBrand())
//                .between(requestParams.getMinPrice() != null && requestParams.getMaxPrice() != null, Item::getPrice, requestParams.getMinPrice()*100, requestParams.getMaxPrice()*100);


        // 构建查询条件
        if (Objects.nonNull(requestParams.getKey()) && !requestParams.getKey().isEmpty()) {
            lqw.like(Item::getName, requestParams.getKey());
        } else {
            //如果关键字为空，优先从redis中获取前20条热销产品
            String key = "HotSold::";
            String json = stringRedisTemplate.opsForValue().get(key);
            if (json != null && requestParams1.equals(requestParams)) {
                List<Item> itemList = JSONUtil.toList(json, Item.class);
                pageDTO.setList(itemList);
                pageDTO.setTotal(20L);
                return pageDTO;
            }
        }

        if (Objects.nonNull(requestParams.getCategory()) && !requestParams.getCategory().isEmpty()) {
            lqw.eq(Item::getCategory, requestParams.getCategory());
        }

        if (Objects.nonNull(requestParams.getBrand()) && !requestParams.getBrand().isEmpty()) {
            lqw.eq(Item::getBrand, requestParams.getBrand());
        }

        if (Objects.nonNull(requestParams.getMinPrice()) && Objects.nonNull(requestParams.getMaxPrice())) {
            lqw.between(Item::getPrice, requestParams.getMinPrice() * 100, requestParams.getMaxPrice() * 100);
        }

        if (Objects.nonNull(requestParams.getSortBy()) && !requestParams.getSortBy().isEmpty()) {
            switch (requestParams.getSortBy()) {
                case "price":
                    lqw.orderByAsc(Item::getPrice);
                    break;
                case "sold":
                    lqw.orderByDesc(Item::getSold);
                    break;
                default:
                    // 默认不排序或按其他字段排序
                    break;
            }
        }

        IPage<Item> iPage1 = itemMapper.selectPage(iPage, lqw);
        pageDTO.setTotal(iPage1.getTotal());
        pageDTO.setList(iPage1.getRecords());
        return pageDTO;*/


        //1.封装请求对象
        SearchRequest request = new SearchRequest("items");

        //1.1设置默认的请求参数
        RequestParams defaultRequestParams = new RequestParams();
        defaultRequestParams.setKey("");
        defaultRequestParams.setPage(1);
        defaultRequestParams.setSize(20);
        defaultRequestParams.setSortBy("default");
        //1.2定义一个集合，准备封装数据
        ArrayList<Item> list = new ArrayList<>();

        //2.封装请求参数
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //2.1判断关键字
        if (StrUtil.isNotEmpty(requestParams.getKey())) {
            //关键字不为空 分词查询
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", requestParams.getKey()));
        } else {
            //如果关键字为空，优先从redis中获取前20条热销产品
            String key = "HotSold::";
            String json = stringRedisTemplate.opsForValue().get(key);
            if (json != null && defaultRequestParams.equals(requestParams)) {
                List<Item> itemList = JSONUtil.toList(json, Item.class);
                return PageDTO.of(20L, itemList);
            }
        }
        //2.2 判断品牌
        if (StrUtil.isNotEmpty(requestParams.getBrand())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("brand", requestParams.getBrand()));
        }

        //2.3 判断分类
        if (StrUtil.isNotEmpty(requestParams.getCategory())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("category", requestParams.getCategory()));
        }
        //2.4判断价格
        if (requestParams.getMinPrice() != null && requestParams.getMaxPrice() != null) {
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price")
                    .gte(requestParams.getMinPrice()*100)
                    .lte(requestParams.getMaxPrice()*100));
        }
        //2.5 判断排序规则
        request.source().from((requestParams.getPage() - 1) * requestParams.getSize()).size(requestParams.getSize());

        //2.6判断筛选条件（价格筛选、销量筛选）
        if (StrUtil.isNotEmpty(requestParams.getSortBy())) {
            switch (requestParams.getSortBy()) {
                case "price": {
                    request.source().sort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
                }
                case "sold": {
                    request.source().sort(SortBuilders.fieldSort("sold").order(SortOrder.DESC));
                }
            }
        }
        //将bool参数封装给request对象
        request.source().query(boolQueryBuilder);
        //3.调用RestHighLevelClient

        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            //4.解析结果
            SearchHits hits = response.getHits();
            long total = hits.getTotalHits().value;
            SearchHit[] smallHits = hits.getHits();
            if (smallHits.length > 0) {
                for (SearchHit hit : smallHits) {
                    //先获取hit里面的source
                    String sourceAsString = hit.getSourceAsString();
                    //将sourceAsString转为item对象
                    Item item = JSONUtil.toBean(sourceAsString, Item.class);
                    list.add(item);
                }
                return PageDTO.of(total, list);
            }
        } catch (Exception e) {
            throw new RuntimeException("中间出故障啦~~，故障信息为：" + e);
        }
        return null;
    }
}